home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Tools / Languages / Python 1.1 / Mac / fopenRF.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-05-06  |  6.2 KB  |  400 lines  |  [TEXT/KAHL]

  1.  
  2. /*
  3.  *  fopenRF.c -- Clone of fopen.c to open Mac resource forks.
  4.  *
  5.  *  Copyright (c) 1989 Symantec Corporation.  All rights reserved.
  6.  *
  7.  */
  8.  
  9. #include "stdio.h"
  10. #include "errno.h"
  11. #include "string.h"
  12. #include "ansi_private.h"
  13.  
  14. FILE *fopenRF(char *, char *);
  15. FILE *freopenRF(char *, char *, FILE *);
  16. FILE *__openRF(char *, int, int, FILE *);
  17.  
  18. #include <Files.h>
  19.  
  20. #define fcbVPtr(fcb)        (* (VCB **) (fcb + 20))
  21. #define fcbDirID(fcb)        (* (long *) (fcb + 58))
  22. #define fcbCName(fcb)        (fcb + 62)
  23.  
  24. static void setfiletype(StringPtr, int);
  25. static void stdio_exit(void);
  26. static int fileio(FILE *, int);
  27. static int close(FILE *);
  28. static void replace(unsigned char *, size_t, int, int);
  29.  
  30.  
  31. FILE *
  32. fopenRF(filename, mode)
  33. char *filename, *mode;
  34. {
  35.     return(freopenRF(filename, mode, __getfile()));
  36. }
  37.  
  38.  
  39. FILE *
  40. freopenRF(filename, mode, fp)
  41. char *filename;
  42. register char *mode;
  43. register FILE *fp;
  44. {
  45.     int omode, oflag;
  46.     
  47.         /*  interpret "rwa"  */
  48.     
  49.     if (mode[0] == 'r') {
  50.         omode = fsRdPerm;
  51.         oflag = 0;
  52.     }
  53.     else if (mode[0] == 'w') {
  54.         omode = fsWrPerm;
  55.         oflag = F_CREAT+F_TRUNC;
  56.     }
  57.     else if (mode[0] == 'a') {
  58.         omode = fsWrPerm;
  59.         oflag = F_CREAT+F_APPEND;
  60.     }
  61.     else {
  62.         errno = EINVAL;
  63.         return(NULL);
  64.     }
  65.         
  66.         /*  interpret "b+"  */
  67.         
  68.     if (mode[1] == 'b') {
  69.         oflag |= F_BINARY;
  70.         if (mode[2] == '+')
  71.             omode = fsRdWrPerm;
  72.     }
  73.     else if (mode[1] == '+') {
  74.         omode = fsRdWrPerm;
  75.         if (mode[2] == 'b')
  76.             oflag |= F_BINARY;
  77.     }
  78.     
  79.         /*  open the file  */
  80.         
  81.     return(__openRF(filename, omode, oflag, fp));
  82. }
  83.  
  84.  
  85. FILE *
  86. __openRF(filename, omode, oflag, fp)
  87. char *filename;
  88. int omode, oflag;
  89. register FILE *fp;
  90. {
  91.     ioParam pb;
  92.     char pname[FILENAME_MAX];
  93.  
  94.     if (fp == NULL)
  95.         return(NULL);
  96.     fclose(fp);
  97.     
  98.         /*  set up pb  */
  99.     
  100.     pb.ioNamePtr = __c2p(filename, pname);
  101.     pb.ioVRefNum = 0;
  102.     pb.ioVersNum = 0;
  103.     pb.ioPermssn = omode;
  104.     pb.ioMisc = 0;
  105.  
  106.         /*  create file  */
  107.  
  108.     if (oflag & F_CREAT) {
  109.         asm {
  110.             lea        pb,a0
  111.             _PBCreate
  112.         }
  113.         if (pb.ioResult == noErr)
  114.             oflag &= ~F_TRUNC;
  115.         else if (pb.ioResult == dupFNErr && !(oflag & F_EXCL))
  116.             oflag &= ~F_CREAT;
  117.         else {
  118.             errno = pb.ioResult;
  119.             return(NULL);
  120.         }
  121.     }
  122.     
  123.         /*  open resource file  */
  124.         
  125.     asm {
  126.         lea        pb,a0
  127.         _PBOpenRF
  128.     }
  129.     if (pb.ioResult) {
  130.         errno = pb.ioResult;
  131.         if (oflag & F_CREAT) asm {
  132.             lea        pb,a0
  133.             _PBDelete
  134.         }
  135.         return(NULL);
  136.     }
  137.     fp->refnum = pb.ioRefNum;
  138.     
  139.         /*  get/set file length  */
  140.         
  141.     if (oflag & F_TRUNC) asm {
  142.         lea        pb,a0
  143.         _PBSetEOF
  144.     }
  145.     else if (!(oflag & F_CREAT)) asm {
  146.         lea        pb,a0
  147.         _PBGetEOF
  148.     }
  149.     fp->len = (fpos_t) pb.ioMisc;
  150.         
  151.         /*  initialize rest of FILE structure  */
  152.         
  153.     if (oflag & F_APPEND) {
  154.         fp->append = 1;
  155.         fp->pos = fp->len;
  156.     }
  157.     if (oflag & F_BINARY)
  158.         fp->binary = 1;
  159.     setvbuf(fp, NULL, _IOFBF, BUFSIZ);
  160.     fp->proc = fileio;
  161.  
  162.         /*  set file type  */
  163.  
  164.     if (oflag & (F_CREAT|F_TRUNC))
  165.         setfiletype(pb.ioNamePtr, oflag);
  166.         
  167.         /*  done  */
  168.         
  169.     __atexit_stdio(stdio_exit);
  170.     return(fp);
  171. }
  172.  
  173.  
  174. /*
  175.  *  setfiletype - set type/creator of new file
  176.  *
  177.  */
  178.  
  179. static void
  180. setfiletype(name, oflag)
  181. StringPtr name;
  182. int oflag;
  183. {
  184.     fileParam pb;
  185.     
  186.     pb.ioNamePtr = name;
  187.     pb.ioVRefNum = 0;
  188.     pb.ioFVersNum = 0;
  189.     pb.ioFDirIndex = 0;
  190.     asm {
  191.         lea        pb,a0
  192.         _PBGetFInfo
  193.         bmi.s    @1
  194.     }
  195.     pb.ioFlFndrInfo.fdType = pb.ioFlFndrInfo.fdCreator = '????';
  196.     if (!(oflag & F_BINARY))
  197.         pb.ioFlFndrInfo.fdType = 'TEXT';
  198.     asm {
  199.         lea        pb,a0
  200.         _PBSetFInfo
  201. @1    }
  202. }
  203.  
  204.  
  205. /*
  206.  *  stdio_exit - stdio shutdown routine
  207.  *
  208.  */
  209.  
  210. static void
  211. stdio_exit()
  212. {
  213.     register FILE *fp;
  214.     int n;
  215.     
  216.     for (fp = &__file[0], n = FOPEN_MAX; n--; fp++)
  217.         fclose(fp);
  218. }
  219.  
  220.  
  221. /*
  222.  *  fileio - I/O handler proc for files and devices
  223.  *
  224.  */
  225.  
  226. static int
  227. fileio(fp, i)
  228. register FILE *fp;
  229. int i;
  230. {
  231.     ioParam pb;
  232.     
  233.     pb.ioRefNum = fp->refnum;
  234.     switch (i) {
  235.     
  236.                 /*  read  */
  237.             
  238.         case 0:
  239.             pb.ioBuffer = (Ptr) fp->ptr;
  240.             pb.ioReqCount = fp->cnt;
  241.             pb.ioPosMode = fp->refnum > 0 ? fsFromStart : fsAtMark;
  242.             pb.ioPosOffset = fp->pos - fp->cnt;
  243.             asm {
  244.                 lea        pb,a0
  245.                 _PBRead
  246.             }
  247.             if (pb.ioResult == eofErr) {
  248.                 fp->pos = pb.ioPosOffset;
  249.                 if (fp->cnt = pb.ioActCount)
  250.                     pb.ioResult = 0;
  251.                 else {
  252.                     fp->eof = 1;
  253.                     return(EOF);
  254.                 }
  255.             }
  256.             if (pb.ioResult) {
  257.                 fp->pos -= fp->cnt;
  258.                 fp->cnt = 0;
  259.             }
  260.             else if (!fp->binary)
  261.                 replace(fp->ptr, fp->cnt, '\r', '\n');
  262.             break;
  263.             
  264.                 /*  write  */
  265.  
  266.         case 1:
  267.             pb.ioBuffer = (Ptr) fp->ptr;
  268.             pb.ioReqCount = fp->cnt;
  269.             pb.ioPosMode = fp->refnum > 0 ? fsFromStart : fsAtMark;
  270.             if ((pb.ioPosOffset = fp->pos - fp->cnt) > fp->len) {
  271.                 pb.ioMisc = (Ptr) pb.ioPosOffset;
  272.                 asm {
  273.                     lea        pb,a0
  274.                     _PBSetEOF
  275.                     bmi.s    @1
  276.                 }
  277.             }
  278.             if (!fp->binary)
  279.                 replace(fp->ptr, fp->cnt, '\n', '\r');
  280.             asm {
  281.                 lea        pb,a0
  282.                 _PBWrite
  283. @1            }
  284.             if (pb.ioResult) {
  285.                 fp->pos -= fp->cnt;
  286.                 fp->cnt = 0;
  287.             }
  288.             else if (pb.ioPosOffset > fp->len)
  289.                 fp->len = pb.ioPosOffset;
  290.             break;
  291.             
  292.                 /*  close  */
  293.  
  294.         case 2:
  295.             pb.ioResult = close(fp);
  296.             break;
  297.     }
  298.     
  299.         /*  done  */
  300.         
  301.     if (pb.ioResult) {
  302.         fp->err = 1;
  303.         errno = pb.ioResult;
  304.         return(EOF);
  305.     }
  306.     return(0);
  307. }
  308.  
  309.  
  310. static int
  311. close(fp)
  312. register FILE *fp;
  313. {
  314.     HFileParam pb;
  315.     Str255 buf;
  316.     register char *fcb = FCBSPtr + fp->refnum;
  317.     VCB *vcb = fcbVPtr(fcb);
  318.     register char *s;
  319.     
  320.     pb.ioNamePtr = buf;
  321.     pb.ioFRefNum = fp->refnum;
  322.     pb.ioVRefNum = vcb->vcbVRefNum;
  323.     pb.ioFVersNum = 0;
  324.     
  325.         /*  close temporary file - HFS  */
  326.         
  327.     if (fp->delete && vcb->vcbSigWord == 0x4244) {
  328.         pb.ioDirID = fcbDirID(fcb);
  329.         s = fcbCName(fcb);
  330.         asm {
  331.             lea        buf,a0
  332.             moveq    #0,d0
  333.             move.b    (s),d0
  334. @1            move.b    (s)+,(a0)+
  335.             dbra    d0,@1
  336.             lea        pb,a0
  337.             _PBClose
  338.             bmi.s    @9
  339.             _PBHDelete
  340.         }
  341.     }
  342.     
  343.         /*  close temporary file - MFS  */
  344.         
  345.     else if (fp->delete && vcb->vcbSigWord == 0xD2D7) {
  346.         pb.ioFDirIndex = 1;
  347.         do asm {
  348.             lea        pb,a0
  349.             _PBGetFInfo
  350.             bmi.s    @2
  351.             addq.w    #1,pb.ioFDirIndex
  352.         } while (pb.ioFRefNum != fp->refnum);
  353.         asm {
  354.             lea        pb,a0
  355.             _PBClose
  356.             bmi.s    @9
  357.             _PBDelete
  358.         }
  359.     }
  360.     
  361.         /*  normal case - just close file  */
  362.         
  363.     else {
  364.         asm {
  365. @2            lea        pb,a0
  366.             _PBClose
  367.             bmi.s    @9
  368.         }
  369.     }
  370.     
  371.         /*  flush volume buffer  */
  372.         
  373.     pb.ioNamePtr = 0;
  374.     asm {
  375.         lea        pb,a0
  376.         _PBFlshVol
  377. @9    }
  378.     return(pb.ioResult);
  379. }
  380.  
  381.  
  382. /*
  383.  *  replace - routine for doing CR/LF conversion
  384.  *
  385.  */
  386.  
  387. static void
  388. replace(s, n, c1, c2)
  389. register unsigned char *s;
  390. register size_t n;
  391. register int c1, c2;
  392. {
  393.     register unsigned char *t;
  394.     
  395.     for (; n && (t = memchr(s, c1, n)); s = t) {
  396.         *t++ = c2;
  397.         n -= t - s;
  398.     }
  399. }
  400.